#include <stdio.h>
#include <stdlib.h>
#include "z_logger.h"
#include "../hisdata/hisdata.h"

#define TAG_HEAD1 0b1010101 //二进制55
#define TAG_HEAD2 0b10101010 //二进制aa

static block_t block;

static int min_tag = 0, max_tag = 0xffff;

typedef struct _his_value_t {
    uint32_t dev_id;
    uint32_t hour;
    uint32_t tag_id;
} his_value_t;

static his_value_t id = {-1, -1, -1};

//读取数据
static int read_payload_pub(char *file_path) {
    int rs = 0, position = 0;
    FILE *file = fopen(file_path, "rb");
    //定位至上次发送后的位置
    fseek(file, position, SEEK_SET);

    //读取头部
    while (0 != fread(&block.head, sizeof(block.head), 1, file)) {
        uint16_t data_length = block.head.len;

        char data_buf[data_length];
        bzero(data_buf, sizeof(data_buf));

        //读取数据部分
        fread(data_buf, data_length, 1, file);

        //读取尾部
        fread(&block.tail, sizeof(block.tail), 1, file);


        //判断存储是否有问题
        if (TAG_HEAD1 != block.tail.eof[1] && TAG_HEAD2 != block.tail.eof[0]) {
            printf("数据块尾部错误！文件存在问题");
            //轮询偏移值，去寻找最近的一个blockhead开头的
            int cycle = 1;
            fseek(file, position + cycle, SEEK_SET);
            bzero(data_buf, sizeof(data_buf));
            while (0 != fread(&block.head, sizeof(block.head), 1, file)) {
                if (TAG_HEAD1 == block.head.bof[0] && TAG_HEAD2 == block.head.bof[1]) {
                    fseek(file, position + cycle, SEEK_SET);
                    position = ftell(file);
                    read_payload_pub(file_path);
                }
                fseek(file, position + ++cycle, SEEK_SET);
            }
        } else {
            void *p;
            uint32_t *timestamp = &block.head.timestamp;
            p = data_buf;
            hdb_header_t *hdb_header = (hdb_header_t *) p;
            int num_tag = hdb_header->n_tags;
            p += sizeof(hdb_header_t);
            //循环num_tag个tag_header和具体的tag_value
            for (int i = 0; i < num_tag; i++) {
                tag_header_t *tag_header = (tag_header_t *) p;
                p += sizeof(tag_header_t);
                //读取value
                float *value = p;
                p += sizeof(float);
                if (tag_header->has_timestamp) {
                    timestamp = p;
                    p += sizeof(uint32_t);
                }
                float tag_value = *value;
                time_t t = *timestamp;
                struct tm *log_time = localtime(&t);;
                if (-1 != id.dev_id && hdb_header->dev_id != id.dev_id) continue;
                if (-1 != id.hour && log_time->tm_hour != id.hour) continue;
                if (tag_header->tag_id >= min_tag && tag_header->tag_id <= max_tag) {
                    printf("log time : %d-%d-%d %d:%d:%d\n", 1900 + log_time->tm_year, 1 + log_time->tm_mon,
                           log_time->tm_mday, log_time->tm_hour, log_time->tm_min, log_time->tm_sec);
                    printf("dev_id = %hu,tag_id = %d, value = %.2f\n", hdb_header->dev_id, tag_header->tag_id,
                           tag_value);
                }
            }
        }
    }
    fclose(file);
    return rs;
}

int main(int argc, char *argv[]) {
    int i;
    char file[MAX_INPUT];

    if (argc == 1) {
        printf("usage: %s -f file_name [-d <dev_id>] [-h <hour>] [--min <min_tag>] [--max <max_tag>]\n",
               argv[0]);
        return EXIT_SUCCESS;
    }

    for (i = 1; i < argc; ++i) {
        if (!strcmp("-d", argv[i])) {
            id.dev_id = atoi(argv[++i]);
        } else if (!strcmp("-h", argv[i])) {
            id.hour = atoi(argv[++i]);
        } else if (!strcmp("-f", argv[i])) {
            sprintf(file, "%s", argv[++i]);
        } else if (!strcmp("--min", argv[i])) {
            min_tag = atoi(argv[++i]);
        } else if (!strcmp("--max", argv[i])) {
            max_tag = atoi(argv[++i]);
        } else {
            printf("usage: %s -f file_name [-d <dev_id>] [-h <hour>] [--min <min_tag>] [--max <max_tag>]\n",
                   argv[0]);
            return EXIT_SUCCESS;
        }
    }
    log_init();
    char file_path[MAX_INPUT] = "";
    strcat(file_path, file);
    read_payload_pub(file_path);

    log_fini();

    return EXIT_SUCCESS;
}
